package cn.dongqihong.license;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import oshi.SystemInfo;
import oshi.hardware.ComputerSystem;
import oshi.hardware.HardwareAbstractionLayer;

import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Todo 请添加类描述
 *
 * @author DongQihong
 * @since 2021/8/3
 */
@Configuration
@EnableConfigurationProperties(LicenseProperties.class)
public class AutoLicenseConfiguration {
    private final static Logger logger = LoggerFactory.getLogger(AutoLicenseConfiguration.class);
    private static SystemInfo systemInfo = new SystemInfo();
    private static HardwareAbstractionLayer hardware = systemInfo.getHardware();
    private static ComputerSystem computerSystem = hardware.getComputerSystem();
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    /**
     * 获取当前运行文件所在的路径
     *
     * @return
     */
    public static String currentPath() {
        String path;
        URL url = LicenseProperties.class.getProtectionDomain().getCodeSource().getLocation();
        File file = new File(url.getPath());
        if (file.isDirectory()) {
            path = file.getAbsolutePath();
        } else {
            path = file.getParent();
        }
        try {
            path = java.net.URLDecoder.decode(path, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            logger.warn(e.getMessage());
        }
        if (!path.endsWith(File.separator)) {
            path += File.separator;
        }
        return path.replace("target/classes/".replace('/', File.separatorChar), "");
    }

    public static String readLicense(LicenseProperties properties) {
        String licPath = properties.getLicPath();
        if (!licPath.startsWith(File.pathSeparator)) {
            licPath = currentPath() + licPath;
        }
        File file = new File(licPath);
        BufferedReader reader = null;
        String licenseCode = null;
        try {
            reader = new BufferedReader(new FileReader(file));
            licenseCode = reader.readLine();
            reader.close();
        } catch (IOException e) {
            logger.warn(e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
        if (licenseCode != null) {
            try {
                return RsaUtils.decrypt(licenseCode, properties.getPubKey());
            } catch (Exception e) {
                logger.warn(e.getMessage());
            }
        }
        return null;
    }

    @Bean
    public License getLicense(LicenseProperties properties) {
        License license = new License();
        String licenseStr = readLicense(properties);
        if (licenseStr == null) {
            logger.error("未找到license授权");
            license.setValid(false);
            return license;
        }
        String[] strings = licenseStr.split("\n");
        for (String string : strings) {
            try {
                if (string.indexOf("产品序列号") >= 0) {
                    license.setProductSerialNumber(string.split(":")[1].trim());
                }
                if (string.indexOf("产品名称") >= 0) {
                    license.setProductName(string.split(":")[1].trim());
                }
                if (string.indexOf("产品使用人") >= 0) {
                    license.setProductUser(string.split(":")[1].trim());
                }
                if (string.indexOf("授权截止日期") >= 0) {
                    String expirationDate = string.split(":")[1].trim();
                    license.setExpirationDate(dateFormat.parse(expirationDate));
                }
            } catch (Exception e) {
                continue;
            }
        }
        license.setValid(verify(license));
        return license;
    }

    /**
     * 验证license
     *
     * @param license
     * @return
     */
    public boolean verify(License license) {
        String serialNumber = generateProductSerialNumber();
        if (!serialNumber.equals(license.getProductSerialNumber())) {
            logger.error("license授权异常");
            return false;
        }
        if (new Date().after(license.getExpirationDate())) {
            logger.error("license授权已到期");
            return false;
        }
        return true;
    }

    /**
     * 生成产品序列号
     *
     * @return
     */
    public static String generateProductSerialNumber() {
        String serialNumber = computerSystem.getHardwareUUID();
        if (serialNumber == null) {
            serialNumber = "0000000000000";
        }
        return serialNumber;
    }

}
